package utils;

import cn.hutool.core.util.ReflectUtil;
import config.DruidConfig;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;

public class MapperProxy<T> implements MethodInterceptor {

    public static DataSource dataSource = DruidConfig.getDataSource();

    private static MapperProxy mapperProxy;

    private MapperProxy() {
    }

    public static <T> MapperProxy<T> getInstance() {
        if (mapperProxy == null) {
            mapperProxy = new MapperProxy<T>();
        }
        return new MapperProxy<>();
    }

    @SuppressWarnings("unchecked")
    public T getProxy(T target) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return (T) enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        Field conn = ReflectUtil.getField(obj.getClass(), "conn");
        Connection connection = dataSource.getConnection();
        if (conn != null) {
            ReflectUtil.setAccessible(conn);
            ReflectUtil.setFieldValue(obj, conn, connection);
        }
        Object result = proxy.invokeSuper(obj, args);
        connection.close();
        return result;
    }
}
